package co.edu.usbcali.unidades.presentation.backingBeans;

import co.edu.usbcali.unidades.exceptions.*;
import co.edu.usbcali.unidades.modelo.*;
import co.edu.usbcali.unidades.modelo.dto.InmuebleDTO;
import co.edu.usbcali.unidades.presentation.businessDelegate.BusinessDelegatorView;
import co.edu.usbcali.unidades.utilities.*;

import com.icesoft.faces.async.render.RenderManager;
import com.icesoft.faces.async.render.Renderable;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.HtmlInputText;
import com.icesoft.faces.component.ext.HtmlInputTextarea;
import com.icesoft.faces.component.ext.HtmlSelectOneMenu;
import com.icesoft.faces.component.selectinputdate.SelectInputDate;
import com.icesoft.faces.context.DisposableBean;
import com.icesoft.faces.webapp.xmlhttp.FatalRenderingException;
import com.icesoft.faces.webapp.xmlhttp.PersistentFacesState;
import com.icesoft.faces.webapp.xmlhttp.RenderingException;
import com.icesoft.faces.webapp.xmlhttp.TransientRenderingException;

import java.math.BigDecimal;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;

import javax.faces.event.ValueChangeEvent;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;


/**
*
*
* @author Zathura Code Generator http://code.google.com/p/zathura
*
*/
public class InmuebleView extends DataSource implements Renderable,
    DisposableBean {
    private HtmlInputText txtInmCuotaAdmin;
    private HtmlInputText txtInmDimension;
    private HtmlInputText txtInmNumeroId;
    private HtmlInputText txtDivCodigo_Division;
    private HtmlInputText txtEstCodigo_Estado;
    private HtmlInputText txtInmCodigo;
    private HtmlCommandButton btnSave;
    private HtmlCommandButton btnModify;
    private HtmlCommandButton btnDelete;
    private HtmlCommandButton btnClear;
    private boolean renderDataTable;
    private boolean flag = true;
    private RenderManager renderManager;
    private PersistentFacesState state = PersistentFacesState.getInstance();
    private List<Inmueble> inmueble;
    private List<InmuebleDTO> inmuebleDTO;
    
    
    
    private HtmlSelectOneMenu cmbDivisiones;
    private List<SelectItem> list_divisiones = new ArrayList<SelectItem>();
          
    String codigoDiv="";
   
    
    private boolean popupVisible = false;
    private HtmlSelectOneMenu cmbMulta;
    private List<SelectItem> list_multas = new ArrayList<SelectItem>();
    private HtmlInputTextarea areaObservacion;
    String inmuebleCodigo="";
    
    
    public String action_ok(){
    	action_popUpVisible();    	
    	return "";
    }
    
    public void action_popUpVisible(){
    	popupVisible=!popupVisible;
    }
    
    
    

    public InmuebleView() {
        super("");
    }

    public String action_clear() {
        txtInmCuotaAdmin.setValue("");       
        txtInmDimension.setValue("");        
        txtInmNumeroId.setValue(""); 
        cmbDivisiones.setValue("-1");   
        btnClear.setDisabled(false);

        return "";
    }

    public void listener_txtId(ValueChangeEvent event) {
        if ((event.getNewValue() != null) && !event.getNewValue().equals("")) {
            Inmueble entity = null;

            try {
                String inmCodigo = new String(txtInmCodigo.getValue().toString());
                entity = BusinessDelegatorView.getInmueble(inmCodigo);
            } catch (Exception e) {
                // TODO: handle exception
            }

            if (entity == null) {
                txtInmCuotaAdmin.setDisabled(false);
                txtInmDimension.setDisabled(false);
                txtInmNumeroId.setDisabled(false);
                txtDivCodigo_Division.setDisabled(false);
                txtEstCodigo_Estado.setDisabled(false);
                txtInmCodigo.setDisabled(false);
                btnSave.setDisabled(false);
                btnDelete.setDisabled(true);
                btnModify.setDisabled(true);
                btnClear.setDisabled(false);
            } else {
                txtInmCuotaAdmin.setValue(entity.getInmCuotaAdmin());
                txtInmCuotaAdmin.setDisabled(false);
                txtInmDimension.setValue(entity.getInmDimension());
                txtInmDimension.setDisabled(false);
                txtInmNumeroId.setValue(entity.getInmNumeroId());
                txtInmNumeroId.setDisabled(false);
                txtDivCodigo_Division.setValue(entity.getDivision()
                                                     .getDivCodigo());
                txtDivCodigo_Division.setDisabled(false);
                txtEstCodigo_Estado.setValue(entity.getEstado().getEstCodigo());
                txtEstCodigo_Estado.setDisabled(false);
                txtInmCodigo.setValue(entity.getInmCodigo());
                txtInmCodigo.setDisabled(true);
                btnSave.setDisabled(true);
                btnDelete.setDisabled(false);
                btnModify.setDisabled(false);
                btnClear.setDisabled(false);
            }
        }
    }

    public String action_save() {
        try {
            BusinessDelegatorView.saveInmueble(null, FacesUtils.checkLong(txtInmCuotaAdmin),
                FacesUtils.checkLong(txtInmDimension),
                FacesUtils.checkString(txtInmNumeroId),
                cmbDivisiones.getValue().toString(),
                "7");
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYSAVED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_delete() {
        try {
            BusinessDelegatorView.deleteInmueble(FacesUtils.checkString(
                    txtInmCodigo));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYDELETED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modify() {
        try {
            BusinessDelegatorView.updateInmueble(FacesUtils.checkString(
                    txtInmCodigo), FacesUtils.checkLong(txtInmCuotaAdmin),
                FacesUtils.checkLong(txtInmDimension),
                FacesUtils.checkString(txtInmNumeroId),
                FacesUtils.checkString(txtDivCodigo_Division),
                FacesUtils.checkString(txtEstCodigo_Estado));
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
            action_clear();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        return "";
    }

    public String action_modifyWitDTO(String inmCodigo, Long inmCuotaAdmin,
        Long inmDimension, String inmNumeroId, String divCodigo_Division,
        String estCodigo_Estado) throws Exception {
        try {
            BusinessDelegatorView.updateInmueble(inmCodigo, inmCuotaAdmin,
                inmDimension, inmNumeroId, divCodigo_Division, estCodigo_Estado);
            renderManager.getOnDemandRenderer("InmuebleView").requestRender();
            FacesUtils.addInfoMessage(ZMessManager.ENTITY_SUCCESFULLYMODIFIED);
        } catch (Exception e) {
            //renderManager.getOnDemandRenderer("InmuebleView").requestRender();
            FacesUtils.addErrorMessage(e.getMessage());
            throw e;
        }

        return "";
    }
    
    public void multar(String inmCodigo)throws Exception{
    	try {
    		inmuebleCodigo=inmCodigo;
    		action_popUpVisible();
    		
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}
    }
    
    public String action_multar(){
    	try {
    		String multa=BusinessDelegatorView.getMulta(cmbMulta.getValue().toString()).getMultNombre();
    		Date fechaActual = new Date();
    		Date fecha = new Date(); 
    		fecha.setDate(fechaActual.getDate()-1);
			BusinessDelegatorView.saveMovMesInmueble(null, fecha, inmuebleCodigo, cmbMulta.getValue().toString());
			PropietarioInmueble prop = BusinessDelegatorView.getpropietarioInmuebleCod(inmuebleCodigo);
			GoogleTest g = new GoogleTest();
			g.sendSSLMessage(new String[]{prop.getPersona().getPerCorreo()}, "Multa", "Usted ha sido multado por "+ multa +"\n "+ areaObservacion.getValue().toString(),
                 		"humberto", "humberto.guerrero1@gmail.com", "HAGUERRERO1090630");
			FacesUtils.addInfoMessage("Multa Creada Con Exito");
			action_popUpVisible();
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
		}
    	return "";
    }

    public List<Inmueble> getInmueble() {
        if (flag) {
            try {
                inmueble = BusinessDelegatorView.getInmueble();
                flag = false;
            } catch (Exception e) {
                flag = true;
                FacesUtils.addErrorMessage(e.getMessage());
            }
        }

        return inmueble;
    }

    public boolean isFlag() {
        return flag;
    }

    public void setInmueble(List<Inmueble> inmueble) {
        this.inmueble = inmueble;
    }

    public boolean isRenderDataTable() {
        try {
            if (flag) {
                if (BusinessDelegatorView.findTotalNumberInmueble(codigoDiv) > 0) {
                    renderDataTable = true;
                } else {
                    renderDataTable = false;
                }
            }

            flag = false;
        } catch (Exception e) {
            renderDataTable = false;
            e.printStackTrace();
        }

        return renderDataTable;
    }

    public DataModel getData() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModel(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<Inmueble> getDataPage(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberInmueble = 0;

        try {
            totalNumberInmueble = BusinessDelegatorView.findTotalNumberInmueble(codigoDiv)
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberInmueble) {
            endIndex = totalNumberInmueble;
        }

        try {
            inmueble = BusinessDelegatorView.findPageInmueble(sortColumnName,
                    sortAscending, startRow, endIndex - startRow,codigoDiv);

            // Remove this Renderable from the existing render groups.
            //leaveRenderGroups();        			
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        //joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<Inmueble>(totalNumberInmueble, startRow, inmueble);
    }

    public DataModel getDataDTO() {
        state = PersistentFacesState.getInstance();

        if (onePageDataModel == null) {
            onePageDataModel = new LocalDataModelDTO(pageSize);
        }

        return onePageDataModel;
    }

    /**
    * This is where the Object data is retrieved from the database and
    * returned as a list of objects for display in the UI.
    */
    private DataPage<InmuebleDTO> getDataPageDTO(int startRow, int pageSize) {
        // Retrieve the total number of objects from the database.  This
        // number is required by the DataPage object so the paginator will know
        // the relative location of the page data.
        int totalNumberInmueble = 0;

        try {
            totalNumberInmueble = BusinessDelegatorView.findTotalNumberInmueble(codigoDiv)
                                                       .intValue();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Calculate indices to be displayed in the ui.
        int endIndex = startRow + pageSize;

        if (endIndex > totalNumberInmueble) {
            endIndex = totalNumberInmueble;
        }

        try {
            inmueble = BusinessDelegatorView.findPageInmueble(sortColumnName,
                    sortAscending, startRow, endIndex - startRow,codigoDiv);

            if (Utilities.validationsList(inmueble)) {
                inmuebleDTO = new ArrayList<InmuebleDTO>();

                for (Inmueble inmuebleTmp : inmueble) {
                    InmuebleDTO inmuebleDTO2 = new InmuebleDTO();
                    inmuebleDTO2.setInmCodigo(inmuebleTmp.getInmCodigo()
                                                         .toString());
                    inmuebleDTO2.setInmCuotaAdmin((inmuebleTmp.getInmCuotaAdmin() != null)
                        ? inmuebleTmp.getInmCuotaAdmin().toString() : null);
                    inmuebleDTO2.setInmDimension((inmuebleTmp.getInmDimension() != null)
                        ? inmuebleTmp.getInmDimension().toString() : null);
                    inmuebleDTO2.setInmNumeroId((inmuebleTmp.getInmNumeroId() != null)
                        ? inmuebleTmp.getInmNumeroId().toString() : null);
                    inmuebleDTO2.setDivCodigo_Division((inmuebleTmp.getDivision()
                                                                   .getDivCodigo() != null)
                        ? inmuebleTmp.getDivision().getDivCodigo().toString()
                        : null);
                    inmuebleDTO2.setEstCodigo_Estado((inmuebleTmp.getEstado()
                                                                 .getEstCodigo() != null)
                        ? inmuebleTmp.getEstado().getEstCodigo().toString() : null);
                    inmuebleDTO2.setInmueble(inmuebleTmp);
                    inmuebleDTO2.setInmuebleView(this);
                    inmuebleDTO.add(inmuebleDTO2);
                }
            }

            // Remove this Renderable from the existing render groups.
            leaveRenderGroups();
        } catch (Exception e) {
            FacesUtils.addErrorMessage(e.getMessage());
        }

        // Add this Renderable to the new render groups.
        joinRenderGroups();
        // Reset the dirtyData flag.
        onePageDataModel.setDirtyData(false);
        // This is required when using Hibernate.  If the SessionManager is not
        // cleared or closed objects are cached and stale objects will show up
        // in the table.
        // This way, the detached objects are reread from the database.
        // This call is not required with Hibernate, which uses a Query Hint
        // to clear the l2 cache in the DAO.
        flag = true;

        return new DataPage<InmuebleDTO>(totalNumberInmueble, startRow,
            inmuebleDTO);
    }

    protected boolean isDefaultAscending(String sortColumn) {
        return true;
    }

    /**
    * This method is called when a render call is made from the server. Render
    * calls are only made to views containing an updated record. The data is
    * marked as dirty to trigger a fetch of the updated record from the
    * database before rendering takes place.
    */
    public PersistentFacesState getState() {
        onePageDataModel.setDirtyData();

        return state;
    }

    /**
    * This method is called from faces-config.xml with each new session.
    */
    public void setRenderManager(RenderManager renderManager) {
        this.renderManager = renderManager;
    }

    public void renderingException(RenderingException arg0) {
        if (arg0 instanceof TransientRenderingException) {
        } else if (arg0 instanceof FatalRenderingException) {
            // Remove from existing Customer render groups.
            leaveRenderGroups();
        }
    }

    /**
    * Remove this Renderable from existing uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void leaveRenderGroups() {
        if (Utilities.validationsList(inmuebleDTO)) {
            for (InmuebleDTO inmuebleTmp : inmuebleDTO) {
                renderManager.getOnDemandRenderer("InmuebleView").remove(this);
            }
        }
    }

    /**
    * Add this Renderable to the new uiCustomerBeans render groups.
    * OnDemandRenderers are named/created using the underlying Customer Number.
    */
    private void joinRenderGroups() {
        if (Utilities.validationsList(inmuebleDTO)) {
            for (InmuebleDTO inmuebleTmp : inmuebleDTO) {
                renderManager.getOnDemandRenderer("InmuebleView").add(this);
            }
        }
    }

    public void dispose() throws Exception {
    }

    public RenderManager getRenderManager() {
        return renderManager;
    }

    public void setState(PersistentFacesState state) {
        this.state = state;
    }

    public HtmlInputText getTxtInmCuotaAdmin() {
        return txtInmCuotaAdmin;
    }

    public void setTxtInmCuotaAdmin(HtmlInputText txtInmCuotaAdmin) {
        this.txtInmCuotaAdmin = txtInmCuotaAdmin;
    }

    public HtmlInputText getTxtInmDimension() {
        return txtInmDimension;
    }

    public void setTxtInmDimension(HtmlInputText txtInmDimension) {
        this.txtInmDimension = txtInmDimension;
    }

    public HtmlInputText getTxtInmNumeroId() {
        return txtInmNumeroId;
    }

    public void setTxtInmNumeroId(HtmlInputText txtInmNumeroId) {
        this.txtInmNumeroId = txtInmNumeroId;
    }

    public HtmlInputText getTxtDivCodigo_Division() {
        return txtDivCodigo_Division;
    }

    public void setTxtDivCodigo_Division(HtmlInputText txtDivCodigo_Division) {
        this.txtDivCodigo_Division = txtDivCodigo_Division;
    }

    public HtmlInputText getTxtEstCodigo_Estado() {
        return txtEstCodigo_Estado;
    }

    public void setTxtEstCodigo_Estado(HtmlInputText txtEstCodigo_Estado) {
        this.txtEstCodigo_Estado = txtEstCodigo_Estado;
    }

    public HtmlInputText getTxtInmCodigo() {
        return txtInmCodigo;
    }

    public void setTxtInmCodigo(HtmlInputText txtInmCodigo) {
        this.txtInmCodigo = txtInmCodigo;
    }

    public HtmlCommandButton getBtnSave() {
        return btnSave;
    }

    public void setBtnSave(HtmlCommandButton btnSave) {
        this.btnSave = btnSave;
    }

    public HtmlCommandButton getBtnModify() {
        return btnModify;
    }

    public void setBtnModify(HtmlCommandButton btnModify) {
        this.btnModify = btnModify;
    }

    public HtmlCommandButton getBtnDelete() {
        return btnDelete;
    }

    public void setBtnDelete(HtmlCommandButton btnDelete) {
        this.btnDelete = btnDelete;
    }

    public HtmlCommandButton getBtnClear() {
        return btnClear;
    }

    public void setBtnClear(HtmlCommandButton btnClear) {
        this.btnClear = btnClear;
    }

    public void setRenderDataTable(boolean renderDataTable) {
        this.renderDataTable = renderDataTable;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    public List<InmuebleDTO> getInmuebleDTO() {
        return inmuebleDTO;
    }

    public void setInmuebleDTO(List<InmuebleDTO> inmuebleDTO) {
        this.inmuebleDTO = inmuebleDTO;
    }

    public TimeZone getTimeZone() {
        return java.util.TimeZone.getDefault();
    }
    
    
    public String getCodigoDiv() {
		return codigoDiv;
	}

	public void setCodigoDiv(String codigoDiv) {
		this.codigoDiv = codigoDiv;
	}
	
	public HtmlSelectOneMenu getCmbDivisiones() {    	
    	list_divisiones.clear();
		List<Division> divisiones;
		try {
			divisiones = BusinessDelegatorView.getDivisionUnidad((FacesUtils.getSession().getAttribute("unidadNit")).toString());
			SelectItem item = new SelectItem(-1, "--Seleccione Una Division--");
			list_divisiones.add(item);
			if (divisiones==null){
				throw new Exception("No existen divisiones o se encuentran inactivas");
			}
			for (int i = 0; i < divisiones.size(); i++) {
				if (divisiones.get(i).getEstado().getEstCodigo().equals("1")) {
					item = new SelectItem(divisiones.get(i).getDivCodigo(), divisiones.get(i).getDivNombre());
					list_divisiones.add(item);
				}
			}
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());			
		}
		return cmbDivisiones;
	}

	public void setCmbDivisiones(HtmlSelectOneMenu cmbDivisiones) {
		this.cmbDivisiones = cmbDivisiones;
	}

	

	public List<SelectItem> getList_divisiones() {
		return list_divisiones;
	}

	public void setList_divisiones(List<SelectItem> listDivisiones) {
		list_divisiones = listDivisiones;
	}

	public boolean isPopupVisible() {
		return popupVisible;
	}



	public void setPopupVisible(boolean popupVisible) {
		this.popupVisible = popupVisible;
	}
	
	public HtmlSelectOneMenu getCmbMulta() {		
		list_multas.clear();
		List<Multa> multas;
		try {
			multas = BusinessDelegatorView.getMulta();
			SelectItem item = new SelectItem(-1, "--Seleccione Una Multa--");
			list_multas.add(item);			
			for (int i = 0; i < multas.size(); i++) {				
					item = new SelectItem(multas.get(i).getMulCodigo(), multas.get(i).getMultNombre());
					list_multas.add(item);			
			}
		} catch (Exception e) {
			FacesUtils.addErrorMessage(e.getMessage());
			e.printStackTrace();
		}	
		
		return cmbMulta;
	}

	public void setCmbMulta(HtmlSelectOneMenu cmbMulta) {
		this.cmbMulta = cmbMulta;
	}

	public List<SelectItem> getList_multas() {
		return list_multas;
	}

	public void setList_multas(List<SelectItem> listMultas) {
		list_multas = listMultas;
	}
	
	
	
	

	public HtmlInputTextarea getAreaObservacion() {
		return areaObservacion;
	}

	public void setAreaObservacion(HtmlInputTextarea areaObservacion) {
		this.areaObservacion = areaObservacion;
	}





	/**
    * A special type of JSF DataModel to allow a datatable and datapaginator
    * to page through a large set of data without having to hold the entire
    * set of data in memory at once.
    * Any time a managed bean wants to avoid holding an entire dataset,
    * the managed bean declares this inner class which extends PagedListDataModel
    * and implements the fetchData method. fetchData is called
    * as needed when the table requires data that isn't available in the
    * current data page held by this object.
    * This requires the managed bean (and in general the business
    * method that the managed bean uses) to provide the data wrapped in
    * a DataPage object that provides info on the full size of the dataset.
    */
    private class LocalDataModel extends PagedListDataModel {
        public LocalDataModel(int pageSize) {
            super(pageSize);
        }

        public DataPage<Inmueble> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPage(startRow, pageSize);
        }
    }

    private class LocalDataModelDTO extends PagedListDataModel {
        public LocalDataModelDTO(int pageSize) {
            super(pageSize);
        }

        public DataPage<InmuebleDTO> fetchPage(int startRow, int pageSize) {
            // call enclosing managed bean method to fetch the data
            return getDataPageDTO(startRow, pageSize);
        }
    }
    
    public void listener_cmbDivision(ValueChangeEvent e){
    	try {
			if (!cmbDivisiones.getValue().toString().equals("-1")){					
				codigoDiv = BusinessDelegatorView.getDivision(cmbDivisiones.getValue().toString()).getDivCodigo();				
				if(inmueble!=null){
					inmueble.clear();
					onePageDataModel=null;
				}
				flag=true;
				isRenderDataTable();
			} 
		}catch (Exception e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    }
}
